﻿Imports WPFGlue.Framework

Namespace Commanding
    Public Class FuncCommand(Of TResult)
        Inherits ResultCommand


        Public Shared ReadOnly ExecutedFuncProperty As DependencyProperty = DependencyProperty.Register("ExecutedFunc", GetType(Func(Of TResult)), GetType(FuncCommand(Of TResult)))
        Public Property ExecutedFunc As Func(Of TResult)
            Get
                Return GetValue(ExecutedFuncProperty)
            End Get
            Set(ByVal value As Func(Of TResult))
                SetValue(ExecutedFuncProperty, value)
            End Set
        End Property

        Public Shared ReadOnly CanExecuteFuncProperty As DependencyProperty = DependencyProperty.Register("CanExecuteFunc", GetType(Func(Of Boolean)), GetType(ActionCommand))
        Public Property CanExecuteFunc As Func(Of Boolean)
            Get
                Return GetValue(CanExecuteFuncProperty)
            End Get
            Set(ByVal value As Func(Of Boolean))
                SetValue(CanExecuteFuncProperty, value)
            End Set
        End Property

        Protected Overrides ReadOnly Property SupportsCanExecute As Boolean
            Get
                Return (CanExecuteFunc IsNot Nothing)
            End Get
        End Property

        Protected Overrides Function CreateInstanceCore() As System.Windows.Freezable
            Return New FuncCommand(Of TResult)
        End Function

        Public Overrides Sub Execute(ByVal sender As Object, ByVal parameter As Object)
            If ExecutedFunc IsNot Nothing Then
                Result = ExecutedFunc.Invoke()
            End If
        End Sub

        Public Overrides Function CanExecute(ByVal sender As Object, ByVal parameter As Object) As Boolean
            Dim result As Boolean = False
            If ExecutedFunc IsNot Nothing Then
                If CanExecuteFunc Is Nothing Then
                    result = True
                Else
                    Try
                        result = CanExecuteFunc.Invoke()
                    Finally
                    End Try
                End If
            End If
            Return result
        End Function

    End Class

    Public Class FuncCommand(Of T, TResult)
        Inherits ResultCommand

        Public Shared ReadOnly ExecutedFuncProperty As DependencyProperty = DependencyProperty.Register("ExecutedFunc", GetType(Func(Of T, TResult)), GetType(FuncCommand(Of T, TResult)))
        Public Property ExecutedFunc As Func(Of T, TResult)
            Get
                Return GetValue(ExecutedFuncProperty)
            End Get
            Set(ByVal value As Func(Of T, TResult))
                SetValue(ExecutedFuncProperty, value)
            End Set
        End Property

        Public Shared ReadOnly CanExecuteFuncProperty As DependencyProperty = DependencyProperty.Register("CanExecuteFunc", GetType(Func(Of T, Boolean)), GetType(ActionCommand(Of T)))
        Public Property CanExecuteFunc As Func(Of T, Boolean)
            Get
                Return GetValue(CanExecuteFuncProperty)
            End Get
            Set(ByVal value As Func(Of T, Boolean))
                SetValue(CanExecuteFuncProperty, value)
            End Set
        End Property

        Protected Overrides ReadOnly Property SupportsCanExecute As Boolean
            Get
                Return (CanExecuteFunc IsNot Nothing)
            End Get
        End Property

        Protected Overrides Function CreateInstanceCore() As System.Windows.Freezable
            Return New FuncCommand(Of T, TResult)
        End Function

        Public Overrides Sub Execute(ByVal sender As Object, ByVal parameter As Object)
            Dim p As T = CType(parameter, T)
            If ExecutedFunc IsNot Nothing Then
                Result = ExecutedFunc.Invoke(p)
            End If
        End Sub

        Public Overrides Function CanExecute(ByVal sender As Object, ByVal parameter As Object) As Boolean
            Dim result As Boolean = False
            If ExecutedFunc IsNot Nothing And TypeOf parameter Is T Then
                If CanExecuteFunc Is Nothing Then
                    result = True
                Else
                    Try
                        result = CanExecuteFunc.Invoke(parameter)
                    Finally
                    End Try
                End If
            End If
            Return result
        End Function

    End Class

    Public Class FuncOfObjectObjectCommand
        Inherits FuncCommand(Of Object, Object)

        Protected Overrides Function CreateInstanceCore() As System.Windows.Freezable
            Return New FuncOfObjectObjectCommand
        End Function
    End Class
End Namespace
